"""
@File    :   validate.py
@Time    :   2024/03/25 13:04:07
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   Oauth2客户端相关的pydantic验证模型
"""

from datetime import datetime

from pydantic import BaseModel, Field, HttpUrl, conint, constr, field_serializer

from src.business.admin.system.oauth2.auth.enums import OAuth2GrantTypeEnum
from src.config import get_app_settings
from src.schemas.serializer_func import http_url_list_serializer
from src.schemas.validate import (
    BaseSearchValidateSchemaMixin,
    BaseValidateSchemaConfigMixin,
)

settings = get_app_settings()


class Oauth2ClientCreateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于创建Oauth2客户端的验证模型"""

    expiration_datetime: datetime = Field(default=..., description="过期时间")
    status: bool = Field(default=True, description="状态")
    show_order: int = Field(default=1, ge=1, le=9999999, description="显示顺序")
    remark: str = Field(default="", min_length=1, max_length=300, description="备注")
    client_id: str = Field(
        default=..., min_length=1, max_length=255, description="客户端编号"
    )
    client_secret: str = Field(
        default=..., min_length=1, max_length=255, description="客户端密钥"
    )
    name: str = Field(default=..., min_length=1, max_length=100, description="应用名")
    logo: str = Field(
        default=settings.default_oauth2_client_logo,
        min_length=1,
        max_length=300,
        description="应用图标",
    )
    access_token_expiration_seconds: int = Field(
        default=settings.oauth2_access_token_default_expiration_seconds,
        ge=settings.oauth2_access_token_min_expiration_seconds,
        le=settings.oauth2_access_token_max_expiration_seconds,
        description="访问令牌过期秒数",
    )  # 最多6小时
    refresh_token_expiration_seconds: int = Field(
        default=settings.oauth2_refresh_token_default_expiration_seconds,
        ge=settings.oauth2_refresh_token_min_expiration_seconds,
        le=settings.oauth2_refresh_token_max_expiration_seconds,
        description="刷新令牌过期秒数",
    )  # 最多15天
    authorization_code_expiration_seconds: int = Field(
        default=settings.oauth2_authorization_code_default_expiration_seconds,
        ge=settings.oauth2_authorization_code_min_expiration_seconds,
        le=settings.oauth2_authorization_code_max_expiration_seconds,
        description="授权码过期秒数",
    )  # 默认10分钟, 最多15分钟
    redirect_uris: list[HttpUrl] = Field(
        default_factory=list, description="可重定向的URI地址"
    )
    authorized_grant_types: list[OAuth2GrantTypeEnum] = Field(
        default_factory=list, description="oauth2授权类型"
    )
    scopes: list[constr(min_length=1, max_length=100)] = Field(
        default_factory=list, description="oauth2授权范围"
    )
    auto_approve_scopes: list[constr(min_length=1, max_length=100)] = Field(
        default_factory=list, description="自动赋予的oauth2授权范围"
    )
    additional_information: str = Field(
        default="", min_length=1, max_length=4096, description="附加信息"
    )

    # 字段序列化
    serializer_redirect_uris = field_serializer("redirect_uris", when_used="always")(
        http_url_list_serializer
    )


class Oauth2ClientUpdateValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于修改Oauth2客户端的验证模型"""

    id: int = Field(default=..., ge=1, description="主键")
    expiration_datetime: datetime = Field(default=..., description="过期时间")
    status: bool = Field(default=True, description="状态")
    show_order: int = Field(default=1, ge=1, le=9999999, description="显示顺序")
    remark: str = Field(default="", min_length=1, max_length=300, description="备注")
    client_id: str = Field(
        default=..., min_length=1, max_length=255, description="客户端编号"
    )
    client_secret: str = Field(
        default=..., min_length=1, max_length=255, description="客户端密钥"
    )
    name: str = Field(default=..., min_length=1, max_length=100, description="应用名")
    logo: str = Field(
        default=settings.default_oauth2_client_logo,
        min_length=1,
        max_length=300,
        description="应用图标",
    )
    access_token_expiration_seconds: int = Field(
        default=settings.oauth2_access_token_default_expiration_seconds,
        ge=settings.oauth2_access_token_min_expiration_seconds,
        le=settings.oauth2_access_token_max_expiration_seconds,
        description="访问令牌过期秒数",
    )  # 最多6小时
    refresh_token_expiration_seconds: int = Field(
        default=settings.oauth2_refresh_token_default_expiration_seconds,
        ge=settings.oauth2_refresh_token_min_expiration_seconds,
        le=settings.oauth2_refresh_token_max_expiration_seconds,
        description="刷新令牌过期秒数",
    )  # 最多15天
    authorization_code_expiration_seconds: int = Field(
        default=settings.oauth2_authorization_code_default_expiration_seconds,
        ge=settings.oauth2_authorization_code_min_expiration_seconds,
        le=settings.oauth2_authorization_code_max_expiration_seconds,
        description="授权码过期秒数",
    )  # 默认10分钟, 最多15分钟
    redirect_uris: list[HttpUrl] = Field(
        default_factory=list, description="可重定向的URI地址"
    )
    authorized_grant_types: list[OAuth2GrantTypeEnum] = Field(
        default_factory=list, description="oauth2授权类型"
    )
    scopes: list[constr(min_length=1, max_length=100)] = Field(
        default_factory=list, description="oauth2授权范围"
    )
    auto_approve_scopes: list[constr(min_length=1, max_length=100)] = Field(
        default_factory=list, description="自动赋予的oauth2授权范围"
    )
    additional_information: str = Field(
        default="", min_length=1, max_length=4096, description="附加信息"
    )

    # 字段序列化
    serializer_redirect_uris = field_serializer("redirect_uris", when_used="always")(
        http_url_list_serializer
    )


class Oauth2ClientUpdateStatusValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于单独修改Oauth2客户端状态的验证模型"""

    id: int = Field(default=..., ge=1, description="主键")
    status: bool = Field(default=..., description="状态")  # (True正常 False停用)


class Oauth2ClientDeleteValidateSchema(BaseModel, BaseValidateSchemaConfigMixin):
    """用于删除Oauth2客户端的验证模型"""

    ids: list[conint(ge=1)] = Field(
        default=..., min_length=1, description="需删除的主键列表"
    )


class Oauth2ClientListSearchValidateSchema(BaseModel, BaseSearchValidateSchemaMixin):
    """用于查询OAuth2客户端列表的验证模型"""

    name: str | None = Field(
        default=None,
        description="应用名",
        min_length=1,
        max_length=100,
        json_schema_extra={"str_like_search_type": "complete"},
    )
    status: bool | None = Field(default=None, description="状态")
    remark: str | None = Field(
        default=None,
        description="备注",
        min_length=1,
        max_length=300,
        json_schema_extra={"str_like_search_type": "complete"},
    )
    expiration_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="过期时间",
        json_schema_extra={"allow_order": True},
    )
    create_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="创建时间",
        json_schema_extra={"allow_order": True},
    )
    update_datetime: tuple[datetime, datetime] | None = Field(
        default=None,
        description="修改时间",
        json_schema_extra={"allow_order": True},
    )
    creator_username: str | None = Field(
        default=None,
        min_length=1,
        max_length=20,
        description="创建者用户名",
        json_schema_extra={"str_like_search_type": "complete"},
    )
    updater_username: str | None = Field(
        default=None,
        min_length=1,
        max_length=20,
        description="修改者用户名",
        json_schema_extra={"str_like_search_type": "complete"},
    )
